#pragma once
#include "tcpServer.hpp"
#include <poll.h>
#define NUM 20
#define DFL -1

class PollServer
{
    public:
      PollServer(int port= 8080)
        :_port(port)
      {
         memset(fds,DFL,sizeof(fds));
      }
      void PollServerInit()
      {
        try{
             _lsock = TcpServer::Socket();
             TcpServer::Bind(_lsock,_port);
             TcpServer::Listen(_lsock);
             cout<<"_lsock"<<_lsock<<endl;
             fds[0].fd = _lsock ;
             fds[0].events = POLLIN ;
             fds[0].revents = 0 ;
             TcpServer::SetSockAddr(_lsock);
        }  
        catch(exception& e)
        {
            cout<<"PollServerInit"<<" "<<e.what()<<endl;
        }
      }
      void PollServerStart()
      {
        while(1)
        {
            cout<<"poll start..."<<endl;
            switch(poll(fds,NUM,-1))
            {
                  case 0:
                    cout<<"wait timeout..."<<endl;
                    break;
                  case -1:
                    cerr<<"wait error..."<<endl;
                    break;
                  default:
                    Rervice();
                    break;
              }    
        }
      }
      void Rervice()
      {
          for(int i = 0 ; i < NUM ;i++)
          {
              if( fds[i].fd == DFL)
              {
                  continue;
              }
              if( fds[i].revents & POLLIN )
              {
                  if( fds[i].fd == _lsock )
                  {
                      cout<<"get a newlink..."<<endl;
                      int sock = TcpServer::Accept(_lsock); 
                      Add2Fds(sock);
                  }
                  else{//进行读取
                      char buf[10240]; //直接recv是不一定满足应用层的协议的,epoll中控制
                      size_t s =recv(fds[i].fd,buf,sizeof(buf)-1,0);
                      if( s > 0)
                      {
                          buf[s] = '\0'; 
                          cout<<" get buf#:"<< buf <<endl;
                          /*给予写回*/
                          fds[i].events = 0;
                          fds[i].events = POLLOUT;
                          fds[i].revents = 0;
                      }
                      else if( s ==0  )
                      {
                          cout<<" client close..."<<endl;
                      }
                      else{
                          cerr<< " recv error"<<endl;
                      }
                  } 
              }
              else if( fds[i].revents & POLLOUT )//进行写
              {
                    char buf[1024]={"Thank you! GoodBye!\n"};//进行短链接
                    send(fds[i].fd , buf, sizeof(buf),0);
                    
                    close(fds[i].fd);
                    DelFromFds(i);
              }
          }
      }
      void Add2Fds(int sock)
      {
          int j =0;
          for( ; j < NUM ; j++ ){
             if( fds[j].fd != DFL ) break;
          }
          if( j >= NUM  ){
              cout<<"struct pollfd *pollfd is full..."<<endl;
              close(fds[j].fd);
          }
          fds[j].fd = sock;
          fds[j].events = POLLIN;
          fds[j].revents = 0;
      }
      void DelFromFds(int idx)
      {
          if( idx >=0 && idx <NUM ) fds[idx].fd=fds[idx].events=fds[idx].revents = DFL;
      }
      ~PollServer()
      {}
    private:
      int _lsock;
      int _port;
      struct pollfd fds[NUM];
};
